#include "osdjson.h"
#include <QVariant>
#include "cJSON.h"

OSDJson::OSDJson() :
    m_jsonObject(NULL)
{
}

OSDJson::OSDJson(QString json) :
    m_jsonObject(NULL)
{
    m_jsonObject = cJSON_Parse(json.toStdString().c_str());
}

OSDJson::OSDJson(cJSON *json):
    m_jsonObject(NULL)
{
    m_jsonObject = cJSON_Duplicate(json,1);
}

OSDJson::OSDJson(const OSDJson& obj):
    m_jsonObject(NULL)
{
    deleteJson();
    this->m_jsonObject = cJSON_Duplicate(obj.m_jsonObject,1);
}

OSDJson& OSDJson::operator=(const OSDJson& cls)
{
    if (this != &cls)
    {
        deleteJson();
        this->m_jsonObject = cJSON_Duplicate(cls.m_jsonObject,1);
    }
    return *this;
}


OSDJson::~OSDJson()
{
    deleteJson();
}

void OSDJson::deleteJson()
{
    if (m_jsonObject)
    {
        cJSON_Delete(m_jsonObject);
        m_jsonObject = NULL;
    }
}

bool OSDJson::isValid()
{
    return (m_jsonObject != NULL);
}

void OSDJson::setJsonStr(QString json)
{
    deleteJson();
    m_jsonObject = cJSON_Parse(json.toStdString().c_str());
}

QVariant OSDJson::value(QString key)
{
    QVariant r;

    if (!m_jsonObject)
    {
        return r;
    }

    cJSON *v = cJSON_GetObjectItem(m_jsonObject,key.toStdString().c_str());
    if (!v)
        return r;
    if (v->type == cJSON_Number) {
        r.setValue(v->valuedouble);
    } else if (v->type == cJSON_String) {
        r.setValue(QString(v->valuestring));
    } else if (v->type == cJSON_True) {
        r.setValue(true);
    } else if (v->type == cJSON_False) {
        r.setValue(false);
    }
    return r;
}

OSDJson OSDJson::object(QString key)
{
    if (m_jsonObject)
    {
        cJSON *v = cJSON_GetObjectItem(m_jsonObject,key.toStdString().c_str());
        if (v && (v->type == cJSON_Object || v->type == cJSON_Array))
        {
            OSDJson o(v);
            return o;
        }
    }
    return OSDJson();
}

QList<OSDJson> OSDJson::getObjectArray()
{
    QList<OSDJson> list;
    list.clear();
    for(int i = 0; i < cJSON_GetArraySize(m_jsonObject); i++)
    {
        cJSON *item = cJSON_GetArrayItem(m_jsonObject,i);
        if (item->type == cJSON_Object)
        {
            list.append(OSDJson(item));
        }
    }
    return list;
}

QList<QVariant> OSDJson::getValueArray()
{
    QList<QVariant> list;
    list.clear();
    for(int i = 0; i < cJSON_GetArraySize(m_jsonObject); i++)
    {
        cJSON *v = cJSON_GetArrayItem(m_jsonObject,i);

        QVariant r;
        if (v->type == cJSON_Number) {
            r.setValue(v->valuedouble);
            list.append(r);
        } else if (v->type == cJSON_String) {
            r.setValue(QString(v->valuestring));
            list.append(r);
        } else if (v->type == cJSON_True) {
            r.setValue(true);
            list.append(r);
        } else if (v->type == cJSON_False) {
            r.setValue(false);
            list.append(r);
        }
    }
    return list;
}

void OSDJson::insert(QString key, QVariant v)
{
    if (!m_jsonObject)
    {
        m_jsonObject = cJSON_CreateObject();
    }

    QByteArray ba = key.toLocal8Bit();

    const char *name = ba.data();
    if (v.type() == QVariant::Bool)
    {
        if (v.toBool())
        {
            cJSON_AddTrueToObject(m_jsonObject,name);
        }
        else
        {
            cJSON_AddFalseToObject(m_jsonObject,name);
        }
    }
    else if (v.type() == QVariant::String)
    {
        cJSON_AddStringToObject(m_jsonObject,name,v.toString().toStdString().c_str());
    }
    else if (v.type() == QVariant::Int || v.type() == QVariant::Double)
    {
        if (v.type() == QVariant::Int)
            cJSON_AddNumberToObject(m_jsonObject, name, v.toInt());
        else
            cJSON_AddNumberToObject(m_jsonObject, name, v.toDouble());
    }

}

QString OSDJson::str()
{
    char *str = cJSON_Print(m_jsonObject);
    QString r = QString(str);
    free(str); str = NULL;
    return r;
}
